#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
系统日志管理器
负责记录用户操作和系统接收资料的所有日志
"""

import logging
import socket
import json
from datetime import datetime
from typing import Dict, List, Optional, Any
from dataclasses import dataclass
from enum import Enum

try:
    from src.models.models import OperationLog
    from src.core.database_manager import DatabaseManager
    from src.utils.logger_config import configure_logging_once
except ImportError:
    try:
        from ..models.models import OperationLog
        from ..core.database_manager import DatabaseManager
        from ..utils.logger_config import configure_logging_once
    except ImportError:
        OperationLog = None
        DatabaseManager = None
        configure_logging_once = None

logger = logging.getLogger(__name__)

class LogLevel(Enum):
    """日志级别枚举"""
    INFO = "信息"
    WARNING = "警告"
    ERROR = "错误"
    CRITICAL = "严重"

class OperationType(Enum):
    """操作类型枚举"""
    # 用户操作类型
    USER_LOGIN = "用户登录"
    USER_LOGOUT = "用户登出"
    USER_ADD = "添加用户"
    USER_EDIT = "编辑用户"
    USER_DELETE = "删除用户"
    USER_PASSWORD_CHANGE = "修改密码"
    
    # 样本操作类型
    SAMPLE_ADD = "添加样本"
    SAMPLE_EDIT = "编辑样本"
    SAMPLE_DELETE = "删除样本"
    SAMPLE_QUERY = "查询样本"
    SAMPLE_EXPORT = "导出样本"

    SAMPLE_BATCH_OPERATION = "批量操作样本"
    
    # 系统配置操作
    SYSTEM_CONFIG_UPDATE = "更新系统配置"
    SYSTEM_BACKUP = "系统备份"
    SYSTEM_RESTORE = "系统恢复"
    SYSTEM_MAINTENANCE = "系统维护"
    
    # 通信操作
    COMMUNICATION_CONNECT = "建立连接"
    COMMUNICATION_DISCONNECT = "断开连接"
    COMMUNICATION_SEND = "发送数据"
    COMMUNICATION_RECEIVE = "接收数据"
    COMMUNICATION_ERROR = "通信错误"
    
    # 数据接收类型
    DATA_RECEIVE_SAMPLE = "接收样本数据"
    DATA_RECEIVE_RESULT = "接收检测结果"
    DATA_RECEIVE_IMAGE = "接收图片数据"
    DATA_RECEIVE_CONFIG = "接收配置数据"
    DATA_RECEIVE_COMMAND = "接收指令数据"
    
    # 其他操作
    REPORT_GENERATE = "生成报告"

    DATA_EXPORT = "数据导出"
    DATA_IMPORT = "数据导入"
    SYSTEM_STARTUP = "系统启动"
    SYSTEM_SHUTDOWN = "系统关闭"

@dataclass
class SystemLog:
    """系统日志数据类"""
    id: Optional[int] = None
    log_time: datetime = None
    log_level: LogLevel = LogLevel.INFO
    operation_type: str = ""
    operator: str = ""
    operation_content: str = ""
    ip_address: str = ""
    module: str = ""
    details: Dict[str, Any] = None
    raw_data: str = ""
    
    def __post_init__(self):
        if self.log_time is None:
            self.log_time = datetime.now()
        if self.details is None:
            self.details = {}
        if self.ip_address == "":
            self.ip_address = self._get_local_ip()

    def _get_local_ip(self) -> str:
        """获取本地IP地址"""
        try:
            s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
            s.connect(("8.8.8.8", 80))
            ip = s.getsockname()[0]
            s.close()
            return ip
        except:
            return "127.0.0.1"

class SystemLoggerManager:
    """系统日志管理器"""
    
    def __init__(self, db_manager: DatabaseManager = None):
        self.db_manager = db_manager
        self.current_user = None
        self._setup_logging()
    
    def _setup_logging(self):
        """设置日志配置"""
        # 使用新的日志配置模块，确保只配置一次
        if configure_logging_once:
            try:
                # 配置日志系统
                configure_logging_once(
                    log_level="INFO",
                    log_file="system.log",
                    console_output=True,
                    file_output=True
                )
            except Exception as e:
                # 如果配置失败，使用基本的日志配置
                self._setup_basic_logging()
        else:
            # 如果没有新的配置模块，使用基本配置
            self._setup_basic_logging()
    
    def _setup_basic_logging(self):
        """设置基本日志配置（备用方案）"""
        try:
            # 获取根日志器
            root_logger = logging.getLogger()
            
            # 如果已经有处理器，跳过配置
            if root_logger.handlers:
                return
            
            # 配置控制台日志
            console_handler = logging.StreamHandler()
            console_handler.setLevel(logging.INFO)
            console_formatter = logging.Formatter(
                '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
            )
            console_handler.setFormatter(console_formatter)
            root_logger.addHandler(console_handler)
            
            # 配置文件日志
            try:
                file_handler = logging.FileHandler('system.log', encoding='utf-8')
                file_handler.setLevel(logging.DEBUG)
                file_formatter = logging.Formatter(
                    '%(asctime)s - %(name)s - %(levelname)s - %(message)s'
                )
                file_handler.setFormatter(file_formatter)
                root_logger.addHandler(file_handler)
            except Exception as e:
                print(f"设置文件日志失败: {e}")
                
        except Exception as e:
            print(f"设置基本日志配置失败: {e}")
    
    def set_current_user(self, username: str):
        """设置当前用户"""
        self.current_user = username
        logger.info(f"当前用户设置为: {username}")
    
    def log_user_operation(self, operation_type: str, operation_content: str, 
                          details: Dict[str, Any] = None, log_level: LogLevel = LogLevel.INFO):
        """记录用户操作日志"""
        try:
            # 创建系统日志对象
            system_log = SystemLog(
                log_level=log_level,
                operation_type=operation_type,
                operator=self.current_user or "系统",
                operation_content=operation_content,
                module="用户操作",
                details=details or {}
            )
            
            # 记录到数据库
            if self.db_manager:
                operation_log = OperationLog(
                    id=None,
                    operation_time=system_log.log_time,
                    operator=system_log.operator,
                    operation_type=system_log.operation_type,
                    operation_content=system_log.operation_content,
                    ip_address=system_log.ip_address
                )
                self.db_manager.add_operation_log(operation_log)
            
            # 记录到文件日志
            log_message = f"用户操作 - {operation_type}: {operation_content}"
            if details:
                log_message += f" | 详情: {json.dumps(details, ensure_ascii=False)}"
            
            if log_level == LogLevel.INFO:
                logger.info(log_message)
            elif log_level == LogLevel.WARNING:
                logger.warning(log_message)
            elif log_level == LogLevel.ERROR:
                logger.error(log_message)
            elif log_level == LogLevel.CRITICAL:
                logger.critical(log_message)
            
            return True
        except Exception as e:
            logger.error(f"记录用户操作日志失败: {e}")
            return False
    
    def log_data_reception(self, data_type: str, data_content: str, 
                          source: str = "", raw_data: str = "", 
                          details: Dict[str, Any] = None):
        """记录数据接收日志"""
        try:
            # 创建系统日志对象
            system_log = SystemLog(
                log_level=LogLevel.INFO,
                operation_type=f"接收{data_type}",
                operator="系统",
                operation_content=f"从{source}接收{data_type}: {data_content}",
                module="数据接收",
                details=details or {},
                raw_data=raw_data[:1000] if raw_data else ""  # 限制原始数据长度
            )
            
            # 记录到数据库
            if self.db_manager:
                operation_log = OperationLog(
                    id=None,
                    operation_time=system_log.log_time,
                    operator=system_log.operator,
                    operation_type=system_log.operation_type,
                    operation_content=system_log.operation_content,
                    ip_address=system_log.ip_address
                )
                self.db_manager.add_operation_log(operation_log)
            
            # 记录到文件日志
            log_message = f"数据接收 - {data_type}: {data_content} | 来源: {source}"
            if details:
                log_message += f" | 详情: {json.dumps(details, ensure_ascii=False)}"
            
            logger.info(log_message)
            
            return True
        except Exception as e:
            logger.error(f"记录数据接收日志失败: {e}")
            return False
    
    def log_system_event(self, event_type: str, event_content: str, 
                        log_level: LogLevel = LogLevel.INFO, 
                        details: Dict[str, Any] = None):
        """记录系统事件日志"""
        try:
            # 创建系统日志对象
            system_log = SystemLog(
                log_level=log_level,
                operation_type=event_type,
                operator="系统",
                operation_content=event_content,
                module="系统事件",
                details=details or {}
            )
            
            # 记录到数据库
            if self.db_manager:
                operation_log = OperationLog(
                    id=None,
                    operation_time=system_log.log_time,
                    operator=system_log.operator,
                    operation_type=system_log.operation_type,
                    operation_content=system_log.operation_content,
                    ip_address=system_log.ip_address
                )
                self.db_manager.add_operation_log(operation_log)
            
            # 记录到文件日志
            log_message = f"系统事件 - {event_type}: {event_content}"
            if details:
                log_message += f" | 详情: {json.dumps(details, ensure_ascii=False)}"
            
            if log_level == LogLevel.INFO:
                logger.info(log_message)
            elif log_level == LogLevel.WARNING:
                logger.warning(log_message)
            elif log_level == LogLevel.ERROR:
                logger.error(log_message)
            elif log_level == LogLevel.CRITICAL:
                logger.critical(log_message)
            
            return True
        except Exception as e:
            logger.error(f"记录系统事件日志失败: {e}")
            return False
    
    def log_communication_event(self, event_type: str, event_content: str, 
                               connection_info: Dict[str, Any] = None,
                               data_size: int = 0, success: bool = True):
        """记录通信事件日志"""
        try:
            details = {
                "success": success,
                "data_size": data_size,
                "connection_info": connection_info or {}
            }
            
            # 创建系统日志对象
            system_log = SystemLog(
                log_level=LogLevel.INFO if success else LogLevel.ERROR,
                operation_type=event_type,
                operator="系统",
                operation_content=event_content,
                module="通信管理",
                details=details
            )
            
            # 记录到数据库
            if self.db_manager:
                operation_log = OperationLog(
                    id=None,
                    operation_time=system_log.log_time,
                    operator=system_log.operator,
                    operation_type=system_log.operation_type,
                    operation_content=system_log.operation_content,
                    ip_address=system_log.ip_address
                )
                self.db_manager.add_operation_log(operation_log)
            
            # 记录到文件日志
            log_message = f"通信事件 - {event_type}: {event_content}"
            if connection_info:
                log_message += f" | 连接信息: {json.dumps(connection_info, ensure_ascii=False)}"
            if data_size > 0:
                log_message += f" | 数据大小: {data_size} bytes"
            log_message += f" | 状态: {'成功' if success else '失败'}"
            
            if success:
                logger.info(log_message)
            else:
                logger.error(log_message)
            
            return True
        except Exception as e:
            logger.error(f"记录通信事件日志失败: {e}")
            return False
    
    def get_logs(self, filters: Dict[str, Any] = None) -> List[OperationLog]:
        """获取日志列表"""
        try:
            if self.db_manager:
                return self.db_manager.get_operation_logs(filters)
            return []
        except Exception as e:
            logger.error(f"获取日志列表失败: {e}")
            return []
    
    def clear_logs(self, before_date: datetime = None) -> bool:
        """清理日志"""
        try:
            if self.db_manager:
                # 这里需要在数据库管理器中添加清理日志的方法
                # 暂时返回True
                return True
            return False
        except Exception as e:
            logger.error(f"清理日志失败: {e}")
            return False

# 全局日志管理器实例
_system_logger = None

def get_system_logger() -> SystemLoggerManager:
    """获取全局系统日志管理器实例"""
    global _system_logger
    if _system_logger is None:
        _system_logger = SystemLoggerManager()
    return _system_logger

def set_system_logger(logger_manager: SystemLoggerManager):
    """设置全局系统日志管理器实例"""
    global _system_logger
    _system_logger = logger_manager 